<!-- 树形层级选择器-->
<!-- 1、支持单选、多选 -->
<template>
	<view class="rh-tree-picker-container">
		<view class="picker-item" @click="boo.showPopup = true">
			<slot name="pickerContent" :emitValue="emitValue">
				<view class="picker-label">
					<slot name="label-icon"></slot>
					<text class="label-txt">{{label}}</text>
				</view>
				<view class="picker-content">
					<u--input
						v-model="emitValue"
						disabled :inputAlign="!label || label == '' ? 'left' : 'right'" fontSize="26rpx"
						disabledColor="#ffffff"
						:placeholder="placeholder"
						border="none"
					></u--input>
					<u-icon
						slot="right"
						name="arrow-right"
					></u-icon>
				</view>
			</slot>
		</view>
		<!-- 筛选弹框 -->
		<u-popup :round="40" :show="boo.showPopup" mode="bottom" @close="popupColse">
			<view class="popup-container">
				<view class="popup-title flex-center">
					<text class="title-txt">{{pickerTitle}}</text>
					<view v-if="!multiple" class="title-close" @click="boo.showPopup = false">
						<u-icon name="close" size="32" color="#000"></u-icon>
					</view>
					<view v-else class="submit-btn flex-center" @click="submit">
						<text class="btn-txt">确定</text>
					</view>
				</view>
				<scroll-view scroll-y="true" scroll-with-animation class="scroll-view">
					<view class="model-item" v-for="model in treeList" :key="model.id">
						<view class="model-row flex-between">
							<view class="model-left" @click="switchItem(model)">
								<view :class="['row-icon flex-center', model.isOpen ? 'arrow-down' : 'arrow-right']">
									<u-icon v-if="model.children && model.children.length" name="arrow-down-fill"></u-icon>
									<text v-else class="dot-icon"></text>
								</view>
								<text class="model-label">{{model.label}}</text>
							</view>
							<label class="model-right" v-if="canSelect(model)" @click="checkedItem(model)">
								<radio style="transform: scale(0.8);" :value="model.id" :checked="model.isChecked"/>
							</label>
						</view>
						<view class="model-child" v-show="model.isOpen">
							<row-item v-for="(item, index) in model['children']" :key="item.id" 
							:row="item" :parent="{label: model.label, id: model.id}" :selectParent="selectParent"
							@row-change="rowChange" @row-open="rowOpen"></row-item>
						</view>
					</view>
				</scroll-view>
			</view>
		</u-popup>
	</view>
</template>

<script>
	import {getTreeAreaByScope,getTreeArea} from '@/script/api/common/index.js'
	import rowItem from './row-item.vue'
	import { mapGetters } from "vuex";
	export default {
		name: "rh-tree-picker",
		components:{
			rowItem
		},
		computed: {
			...mapGetters("user", ["roleKey"]),
		},
		props: {
			value: {
				type: Array,
				default: () => []
			},
			label: {
				type: String,
				default: () => ''
			},
			pickerTitle: {
				type: String,
				default: () => '选择区域'
			},
			moduleType: {
				type: String,
				default: () => 'sys'
			},
			placeholder: {
				type: String,
				default: () => '请选择地区'
			},
			multiple: {
				type: Boolean,
				default: () => false
			},
			selectParent: {
				type: Boolean,
				default: () => false
			},
		},
		watch: {
			value: {
				handler(val){
					let _self = this
					if(val && val.length){
						_self.resetList()
					}
				},
				immediate: false,
			},
		},
		data() {
			return {
				boo: {
					showPopup: false
				},
				emitValue: '',
				treeList: []
			}
		},
		mounted() {
			let _self = this
			_self.getTreeAreaList()
		},
		methods: {
			resetList(){
				let _self = this, deepChild = null
				if(!_self.multiple){
					_self.emitValue = _self.value.map(i => i.label).join('/')
				}else{
					let arrStr = []
					_self.value.forEach(arrs => {
						arrStr.push(arrs.map(i => i.label).join('/'))
					})
					_self.emitValue = arrStr.join('、')
				}
				deepChild = (tree, town, village, zireVillage) => {
					tree.forEach(data => {
						// 只有镇
						if(town && !village){
							if(town.id == data.id){
								_self.$set(data, 'isChecked', true)
								_self.$set(data, 'checkedIdArr', [{label: data.label, id: data.id}])
							}
						}
						// 只有行政村
						if(village && !zireVillage){
							if(town.id == data.id){
								_self.$set(data, 'isOpen', true)
							}
							if(village.id == data.id){
								_self.$set(data, 'isChecked', true)
								_self.$set(data, 'checkedIdArr', [town, {label: data.label, id: data.id}])
							}
						}
						// 只有自然村
						if(zireVillage){
							if(town.id == data.id){
								_self.$set(data, 'isOpen', true)
							}
							if(village.id == data.id){
								_self.$set(data, 'isOpen', true)
							}
							if(zireVillage.id == data.id){
								_self.$set(data, 'isChecked', true)
								_self.$set(data, 'checkedIdArr', [town, village, {label: data.label, id: data.id}])
							}
						}
						data.children && deepChild(data.children, town, village, zireVillage) // 遍历子树
					})
				}
				if(!_self.multiple){
					let town = this.value[0] || null, village = this.value[1] || null, zireVillage = this.value[2] || null
					deepChild(_self.treeList, town, village, zireVillage)
				}else{
					_self.value.forEach(arrs => {
						let town = arrs[0] || null, village = arrs[1] || null, zireVillage = arrs[2] || null
						deepChild(_self.treeList, town, village, zireVillage)
					})
				}
			},
			// 获取村镇数据
			getTreeAreaList(){
				let _self = this
				this.roleKey === 'resident' ?
				getTreeArea({
					moduleType: _self.moduleType
				}).then(res => {
					let area = res.data
					_self.treeList = area
					_self.resetList()
				}) :
				getTreeAreaByScope({
					moduleType: _self.moduleType
				}).then(res => {
					let area = res.data
					_self.treeList = area
					_self.resetList()
				})
			},
			canSelect(model){
				let _self = this, {children = []} = model, boo = Boolean
				if(_self.selectParent){
					boo = true
				}else{
					if(children.length){
						boo = false
					}else{
						boo = true
					}
				}
				return boo
			},
			switchItem(model){
				let _self = this
				_self.$set(model, 'isOpen', model.isOpen ? false : true)
				let deepChild = (tree, emit) => {
					tree.forEach(data => {
						if(data['id'] == emit['id']){
							_self.$set(data, 'isOpen', emit['isOpen'])
						}
						data.children && deepChild(data.children, emit) // 遍历子树
					})
				}
				deepChild(_self.treeList, model)
			},
			checkedItem(model){
				let _self = this
				if(!_self.multiple){
					_self.treeList.forEach(item => {
						_self.$set(item, 'isChecked', false)
					})
					_self.$set(model, 'isChecked', model.isChecked ? false : true)
					let areaList = [
						{label: model.label, id: model.id}
					]
					_self.emitValue = model.label
					_self.$emit('select-change', areaList)
					_self.$emit('input', areaList)
					_self.$nextTick(() => {
						_self.boo.showPopup = false
					})
				} else {
					_self.$set(model, 'isChecked', model.isChecked ? false : true)
					if(model['isChecked']){
						_self.$set(model, 'checkedIdArr', [{label: model.label, id: model.id}])
					}else{
						delete model['checkedIdArr']
					}
				}
			},
			rowChange(row){
				let _self = this
				let deepChild = (tree, emit, fn) => {
					tree.forEach(data => {
						if(!_self.multiple){
							_self.$set(data, 'isChecked', false)
						}
						if(data.id == emit['id']){
							_self.$set(data, 'isChecked', emit['isChecked'])
							if(emit['checkedIdArr']){
								_self.$set(data, 'checkedIdArr', emit['checkedIdArr'])
							}else{
								delete data['checkedIdArr']
							}
							fn(data)
						}
						data.children && deepChild(data.children, emit, fn) // 遍历子树
					})
				}
				deepChild(_self.treeList, row, (item) => {
					if(!_self.multiple){
						let labelArr = item['checkedIdArr'].map(i => i.label)
						_self.emitValue = labelArr.join('/')
						_self.$emit('select-change', item['checkedIdArr'])
						_self.$emit('input', item['checkedIdArr'])
						_self.$nextTick(() => {
							_self.boo.showPopup = false
						})
					}
				})
			},
			rowOpen(row){
				let _self = this
				let deepChild = (tree) => {
					tree.forEach(data => {
						if(data.id == row.id){
							_self.$set(data, 'isOpen', row['isOpen'])
						}
						data.children && deepChild(data.children) // 遍历子树
					})
				}
				deepChild(_self.treeList)
			},
			submit(){
				let _self = this, arr = [], arrStr = []
				let deepChild = (tree) => {
					tree.forEach(data => {
						if(data.isChecked){
							arr = [...arr, ...[data['checkedIdArr']]]
						}
						data.children && deepChild(data.children) // 遍历子树
					})
				}
				deepChild(_self.treeList)
				arr.forEach(arrs => {
					arrStr.push(arrs.map(i => i.label).join('/'))
				})
				_self.emitValue = arrStr.join('、')
				_self.$emit('select-change', arr)
				_self.$emit('input', arr)
				_self.$nextTick(() => {
					_self.boo.showPopup = false
				})
			},
			popupColse(){
				let _self = this
				let deepChild = (tree) => {
					tree.forEach(data => {
						delete data['isOpen']
						delete data['isChecked']
						delete data['checkedIdArr']
						data.children && deepChild(data.children) // 遍历子树
					})
				}
				deepChild(_self.treeList)
				_self.resetList()
				_self.$nextTick(() => {
					_self.boo.showPopup = false
				})
			},
		},
	}
</script>

<style scoped lang="scss">
	.scroll-view{
		max-height: 800rpx;
		padding: 0 32rpx;
		.model-item{
			margin-bottom: 24rpx;
			line-height: 48rpx;
			.model-left{
				position: relative;
				padding-left: 46rpx;
				flex: 1;
				.row-icon{
					position: absolute;
					top: 50%;
					transform: translateY(-50%);
					left: 0;
					transition: .3s;
					&.arrow-right{
						transform: translateY(-50%) rotate(-90deg);
					}
					.dot-icon{
						display: block;
						width: 16rpx;
						height: 16rpx;
						background-color: #606266;
						border-radius: 50%;
					}
				}
				.model-label{
					font-size: 28rpx;
					color: rgba(0,0,0,.85);
				}
			}
			.model-child{
				margin-top: 20rpx;
				margin-left: 30rpx;
			}
		}
	}
	.rh-tree-picker-container{
		width: 100%;
		.picker-item{
			display: flex;
			justify-content: space-between;
			align-items: center;
			.picker-label{
				display: flex;
				align-items: center;
				.label-txt{
					font-size: 26rpx;
					color: #666;
				}
			}
			.picker-content{
				flex: 1;
				display: flex;
				align-items: center;
				margin-left: 30rpx;
			}
		}
	}
	.popup-container{
		.popup-title{
			padding: 38rpx 0;
			text-align: center;
			font-size: 32rpx;
			font-weight: 500;
			color: #000;
			position: relative;
			.title-close{
				position: absolute;
				top: 50%;
				transform: translateY(-50%);
				right: 38rpx;
			}
			.submit-btn{
				height: 50rpx;
				position: absolute;
				top: 50%;
				transform: translateY(-50%);
				right: 38rpx;
				border-radius: 6rpx;
				background-color: #389E0D;
				padding: 0 24rpx;
				.btn-txt{
					font-size: 24rpx;
					color: #fff;
				}
			}
		}
		.model-list{
			padding: 0 60rpx 60rpx;
		}
	}
</style>
